/*
 * These files are distributed under the terms of the GNU GPLv2, the GNU General
 * Public version 2. See LICENSE.txt
 */
package fileCommodore.model;

import java.io.*;
import java.util.*;

import javax.swing.*;
import javax.swing.filechooser.*;

import org.apache.commons.vfs.*;

import fileCommodore.*;

/**
 * @author nado18@gmail.com, on Jul 14, 2007
 */
public class FileRowItem implements Comparable<FileRowItem>
{
	private FileObject fo;
	private boolean tagged;
	
	public FileRowItem(FileObject fileObject)
	{
		fo = fileObject;
	}
	
	public String getFileName()
	{
		return fo.getName().getBaseName();
	}
	
	public File toFile()
	// TODO: Compare with Plugin.toFile
	{
		String sUri = fo.getName().getPath();
		File retval = new File( sUri );
		return retval;
	}
	
	private static long getSize( FileObject fo )
	{
		try
		{
			if (isFile( fo ))
			{
				return fo.getContent().getSize();
			}
		}
		catch (FileSystemException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return -1;
	}
	
	public long getSize()
	{
		if (isFile())
		{
			try
			{
				return fo.getContent().getSize();
			}
			catch (FileSystemException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return -1;
	}
	
	public long getRecursiveSize()
	{
		return getRecursiveSize( fo, new HashSet<FileObject>() );
	}
	
	private static long getRecursiveSize( FileObject f,
		HashSet<FileObject> history )
	{
		if (history.contains( f ))
		{
			return 0;
		}
		else
		{
			history.add( f );
			
			if (isFile( f ))
			{
				return getSize( f );
			}
			else if (isDirectory( f ))
			{
				long sum = 0;
				
				try
				{
					for (FileObject sub : f.getChildren())
					{
						sum += getRecursiveSize( sub, history );
					}
				}
				catch (FileSystemException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				return sum;
			}
			else
			{
				return 0;
			}
		}
	}
	
	public static boolean isFile( FileObject fo )
	{
		try
		{
			return FileType.FILE.equals( fo.getType() );
		}
		catch (FileSystemException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}
	
	public boolean isFile()
	{
		return !isDirectory();
	}
	
	public static boolean isDirectory( FileObject fo )
	{
		try
		{
			return FileType.FOLDER.equals( fo.getType() );
		}
		catch (FileSystemException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}
	
	public boolean isDirectory()
	{
		return isDirectory( fo );
	}
	
	public boolean isHidden()
	{
		try
		{
			return fo.isHidden();
		}
		catch (FileSystemException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return false;
	}
	
	public boolean isVisible()
	{
		return !isHidden();
	}
	
	@Override
	public String toString()
	{
		return getFileName();
	}
	
	public boolean matches( String filter )
	{
		filter = filter.toLowerCase();
		String filename = getFileName().toLowerCase();
		return filename.contains( filter );
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo( FileRowItem o )
	{
		try
		{
			if (fo.getType() == o.fo.getType())
			{
				if (Config.isSortCaseSensitive())
				{
					return getFileName().compareTo( o.getFileName() );
				}
				else
				{
					return getFileName().compareToIgnoreCase( o.getFileName() );
				}
			}
			else if (isDirectory())
			{
				return -1;
			}
			else
			{
				return 1;
			}
		}
		catch (FileSystemException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return 0;
	}
	
	@Override
	public boolean equals( Object obj )
	{
		return obj instanceof FileRowItem
				&& fo.equals( ( (FileRowItem) obj ).fo );
	}
	
	public Icon getIcon()
	{
		try
		{
			// TODO: Check if we're on the local file system first
			File f = new File( fo.getName().getPath() );
			Icon icon = FileSystemView.getFileSystemView().getSystemIcon( f );
			return icon;
		}
		catch (Exception ex)
		{
			// TODO: Should we report?
			return null;
		}
	}
	
	public FileObject getFileObject()
	{
		return fo;
	}
	
	public boolean isTagged()
	{
		return tagged;
	}
	
	public void setTagged( boolean tagged )
	{
		this.tagged = tagged;
	}
	
	public void tag()
	{
		setTagged( true );
	}
	
	public void untag()
	{
		setTagged( false );
	}
	
	public void toggleTag()
	{
		setTagged( !isTagged() );
	}
}
